﻿#include "ComClientManage.h"
#include <QApplication>
#include "TcpClient.h"
#include "UdpClient.h"
#include "SerialCom.h"
#include <QSettings>

#pragma execution_character_set("utf-8")

ComClientManage::ComClientManage(QObject *parent)
    : QObject{parent}
{
    //setConfigWriteOneFunc(void (*func)(const ComClientConfig& config));
    //setConfigReadAllFunc(QMap<QString, ComClientConfig> (*func)());
    //setConfigReadOneFunc(ComClientConfig (*func)(QString camName));
    //initWgtComClientStatus();
    //initComClientManageWidget();
    //initComClientAll();
    //startWorker();
#if QT_VERSION >= 0x060000
// Qt 6 的代码
#else
    // Qt 5 的代码
    qRegisterMetaTypeStreamOperators<ComClientConfig>("ComClientConfig");
#endif

    configWriteOne = [](const ComClientConfig& config){
        QSettings iniFile(QApplication::applicationDirPath() + "/Config.ini", QSettings::IniFormat);
        iniFile.setValue("ComClientConfig/" + config.name, QVariant::fromValue(config));
    };
    configReadOne = [](QString name)->ComClientConfig{
        QSettings iniFile(QApplication::applicationDirPath() + "/Config.ini", QSettings::IniFormat);
        ComClientConfig config = iniFile.value("ComClientConfig/" + name).value<ComClientConfig>();
        return config;
    };
    configReadAll = []()->QMap<QString, ComClientConfig>{
        QSettings iniFile(QApplication::applicationDirPath() + "/Config.ini", QSettings::IniFormat);
        iniFile.beginGroup("ComClientConfig");
        QStringList keyList = iniFile.childKeys();
        QMap<QString, ComClientConfig> mapConfig;
        for(auto key : keyList){
            ComClientConfig config = iniFile.value(key).value<ComClientConfig>();
            mapConfig.insert(config.name, config);
        }
        iniFile.endGroup();
        return mapConfig;
    };
}
void ComClientManage::setConfigWriteOneFunc(void (*func)(const ComClientConfig& config))
{
    configWriteOne = func;
}
void ComClientManage::setConfigReadAllFunc(QMap<QString, ComClientConfig> (*func)())
{
    configReadAll = func;
}
void ComClientManage::setConfigReadOneFunc(ComClientConfig (*func)(QString camName))
{
    configReadOne = func;
}
void ComClientManage::startWorker()
{
    for(auto thread : mMapComThread.values()){
        thread->start();
    }
}
void ComClientManage::checkComClientStatus()
{
    bool isStart = true;
    if(mMapComStart.size() != mMapComClient.size()){
        isStart = false;
        goto checkEnd;
    }
    for(auto status : mMapComStart.values()){
        if(!status){
            isStart = false;
            break;
        }
    }
checkEnd:
    emit sigComClientStatus(isStart);
}
void ComClientManage::initComClientAll()
{
    QMap<QString, ComClientConfig> mapComConfig = configReadAll();
    for(auto key : mapComConfig.keys()){
        initComClientOne(mapComConfig.value(key));
    }
}
void ComClientManage::initComClientOne(ComClientConfig config)
{
    ComBase* comWorker;
    switch (config.type) {
    case CCT_Tcp:
        comWorker = new TcpClient();
        break;
    case CCT_Serial:
        comWorker = new SerialCom();
        break;
    case CCT_Udp:
        comWorker = new UdpClient();
        break;
    }
    comWorker->setConfig(config);
    mMapComClient.insert(config.name, comWorker);

    QThread* comThread = new QThread();
    mMapComThread.insert(config.name, comThread);

    comWorker->moveToThread(comThread);
    connect(comThread, &QThread::started, comWorker, &ComBase::onInit);
    connect(qApp, &QApplication::aboutToQuit, comWorker, &ComBase::onQuit);
    connect(comWorker, &QObject::destroyed, comThread, &QThread::quit);
    connect(comThread, &QThread::finished, comThread, &QThread::deleteLater);

    wgtComClientStatus->addOne(config.name);

    //在相机管理页面添加一个
    mComClientManageWidget->addComClient(mMapComClient.value(config.name));

    //连接相机的状态信号，并显示
    QString comName = config.name;
    connect(comWorker, &ComBase::sigStateChanged, this, [&, comName](const ComState& status){
        wgtComClientStatus->setStatus(comName, ComBase::mapComStateText.value(status));
    });

}
void ComClientManage::initWgtComClientStatus()
{
    wgtComClientStatus = new ComClientStatusWidget();
    wgtComClientStatus->setMinimumWidth(200);
}
void ComClientManage::initComClientManageWidget()
{
    mComClientManageWidget = new WidgetComClient("相机调试");
    connect(mComClientManageWidget, &WidgetComClient::sigAddOne, this, &ComClientManage::onAddOne);
    connect(mComClientManageWidget, &WidgetComClient::sigConfigChanged, this, &ComClientManage::onConfigChanged);
    connect(mComClientManageWidget, &WidgetComClient::sigDeleteOne, this, &ComClientManage::onDeleteOne);
}
void ComClientManage::onAddOne(const ComClientConfig& config)
{
    if(mMapComClient.contains(config.name))
        return;
    configWriteOne(config);
    initComClientOne(config);
    mMapComThread.value(config.name)->start();
}
void ComClientManage::onDeleteOne(const QString& name)
{
    if(!mMapComClient.contains(name))
        return;
    ComBase* com = mMapComClient.take(name);
    com->deleteLater();
    com = nullptr;
    wgtComClientStatus->removeOne(name);
}
void ComClientManage::onConfigChanged(const ComClientConfig& config)
{
    configWriteOne(config);
}
